%include "nasm_macros.inc"
%include "os.inc"
section .text 
org 100h
start:
%define FORCE_SIZE (SECT_SZ * 128)
push cs
push cs
pop ds
pop es
call reset
mov dx,file
mov ah,41h
int 21h
xor ecx,ecx
mov dx,file
mov ax,3c00h
int 21h
mov dx,msg3
jc exit
mov [hf],ax
mov dh,DISK_FLOPPY
mov dl,'A' - 'A' + 1
call get_disksize
mov ecx,eax
mov dx,DISK_FLOPPY
mov ax,buf
mov ebx,1   ;00HHCCCS;
mov ecx,FORCE_SIZE
call read_disk
call cleanup
mov dx,msg1
exit:
call msg
xor eax,eax
int 16h 
int 20h
;;;;;;;;;;;;;;;;;;;;;;
msg1 db 'Dump ready!$'
msg2 db 'CHS overflow!$'
msg3 db 'Create file error!$'
msg:
pushad
mov ah,9
int 21h
popad
ret

cleanup:
pushad
mov ah,3eh
mov bx,[hf]
int 21h
popad
ret

reset:
pushad
xor dx,dx
xor ax,ax
int 13h
popad
ret

;;;;;;;;;;;;;;;;;;;;;
;max=0ffffffffh/80h sects
get_disksize:
push dx
mov ah,1ch
int 21h
push cs
pop ds
cmp al,0ffh
jne jgd
mov al,1   ;sec in cluster
mov dx,100 ;clusters
mov cx,200h ;512
jgd:
;dx,al,cx
xor ah,ah
mul dx
mul cx
rol eax,16
mov ax,dx
rol eax,16
pop dx
push eax
mov ah,8
shr dx,8
call int13
;CHS
mov ax,cx
xchg al,ah
shr ah,6  ;ax=cyl
shr dx,8 ;dx=nhdr
mov [ncyl],ax
mov [nhdr],dx
and cx,111111b
mov [nsct],cx
pop eax
xor eax,eax
xor edx,edx
mov ax,[ncyl]
inc ax ;counted from 0
mov bx,[nhdr]
inc bx ;counted from 0
mul bx
rol eax,16
mov ax,dx
rol eax,16
xor ebx,ebx
mov bx,[nsct]
mul ebx
shl eax,SECT_SHIFT
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ds:ax = buf,ebx=chs,ecx=nbytes,dx=disk
read_disk:
pushad
mov ebp,ecx
test ebp,SECT_SZ - 1
je kr1
add ebp,SECT_SZ
kr1:
shr ebp,SECT_SHIFT
mov edi,ebx
mov bx,ax
wdl:
call reset
mov cx,di
rol edi,16
mov ax,di
mov dh,al
rol edi,16
;
mov ah,02h
mov al,1
call int13
jnc jnc0
db 0cch
jnc0:
call payload
mov eax,1
push ebx
mov ebx,edi
call chs_add
mov edi,eax
pop ebx
dec ebp
jnz wdl
popad
ret

;write to file
payload:
pushad
mov ah,40h
mov dx,buf
mov cx,SECT_SZ
mov bx,[hf]
int 21h
popad
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;spoil ebp,ecx,edx,
;eax=chs1,ebx=chs2;-->eax=(chs)(eax+ebx)
chs_add:
push ebx
push ebp
push edx
push 0 ;cary
mov cx,ax
and cx,111111b
mov dx,bx
and dx,111111b
add cx,dx
cmp cx,[nsct] ;cx=sct sum
jbe jbe1
inc word [esp]
mov cx,1
jbe1:
mov ebp,ecx; sect
;
mov cx,ax
xchg cl,ch
shr ch,6  ;cx=cyl1
;
mov dx,bx
xchg dl,dh
shr dh,6  ;dx=cyl2
add cx,dx
add cx,word [esp]
mov word [esp],0
cmp cx,[ncyl] ;cx=cyl sum
jbe jbe2
inc word [esp]
xor cx,cx
jbe2:
xchg cl,ch
shl cl,6  ;dx=cyl2
add ebp,ecx; cyl
;
rol eax,16
rol ebx,16
mov ah,0
mov bh,0
add ax,bx
add ax,word [esp]
or ah,ah
jne addchs_err
rol ebp,16
mov bp,ax
rol ebp,16
pop ax
mov eax,ebp
pop edx
pop ebp
pop ebx
ret
addchs_err:
mov dx,msg2
call exit
ret

int13:
push es
test cl,111111b
jne i13
or cl,1
i13:
int 13h
pop es
ret
;;;;;;;;;;;;data
nsct dw 0
ncyl dw 0
nhdr dw 0
file db 'floppy.bin',0
hf dw 0
buf: